#ifndef MODLUES_HXX
#define MODLUES_HXX

#include <list>
#include <map>
#include "module.hxx"
#include "module_list.hxx"

using std::map;

/*! \enum ModuleExecType
 *
 *  Detailed description
 */
enum ModuleExecType {
    ModuleExecAllType,      // 执行所有enable的模块
    ModuleExecAutoTypeOnly, // 执行enable以及允许auto的模块
};


/*! \enum RequestType
 *
 *  描述一个请求是什么类型
 */
enum RequestType {
    RequestTypeUnknow,
    // 请求获取命令结果
    RequestTypeGetCommandResult,
    // 请求设置执行结果
    RequestTypeSetCommandResult,
    // 请求执行命令
    RequestTypeRunCommand,
    // 请求获取模块的执行时数据
    RequestTypeGetPendingData,
    // 获取模块的数量
    RequestTypeGetCountOfAllModules,
    // 获取一组模块们的执行结果
    RequestTypeGetStatusOfAllModulesWithCount
};

/*! \enum RespondType
 *
 *  对请求进行响应
 */
enum RespondType {
    // 以单个模块与执行结果的方式，返回响应
    RespondTypeModuleResult,
    // 以单个模块与执行数据的方式，返回响应
    RespondTypeModuleResultData,
    // 返回一群模块与执行结果
    RespondTypeModuleResultsForGetStatusOfAllModulesWithCount,
};


#define REQUEST_MAX_DATA_SIZE 128
#define REQUEST_MAGIC         0x7e90e

// client 对 server 所发送的请求
// 这个请求可以是来自socket，也可以是其他数据源
struct moduleRequest
{
    int requestMagic;
    /* 命令是查询还是执行 */
    int type;
    char name[MODULE_NAME_MAX_SIZE];
    /* 数据长度 */
    int dataSize;
    /* 数据 */
    char data[REQUEST_MAX_DATA_SIZE];
    int result;
};
int strs2moduleRequest(const string & run_mode, const string & cmd, const string & set_value,
                       struct moduleRequest *request);

// server 对 client 所发送的请求的响应
struct moduleRespond
{
    /* 命令是查询还是执行 */
    int type;
    /* 数据长度 */
    int size;
    /* 数据 */
    void *data;
};


class TestModulesManager
{
public:
    TestModulesManager(void);
    ~TestModulesManager(void);
    /* 模块管理器的有关方法 */
    // 插入一个模块
    void insertModule(class TestModule* module, void* arg = nullptr);
    // 插入n个模块
    void insertModules(class TestModule* moduleList[], void* arg = nullptr);
    void insertModules(struct TestModuleSt* moduleList, void* arg = nullptr);
    // 查找一个模块
    class TestModule* findModule(const string &name);
    // 执行一个模块
    bool execModuleByName(const string &name);
    // 执行模块时带运行时参数
    bool execModuleWithRuntimeArg(const string &moduleName,
                                  struct moduleRuntimeArg * runtimeArg);
    // 获取模块执行期间的打印信息
    char* getModulePendingDataByName(const string &name);
    bool execAllModules(enum ModuleExecType = ModuleExecAutoTypeOnly,
                        struct moduleRuntimeArg * runtimeArg = nullptr);
    bool getModuleResult(const string &moduleName);
    // 指定模块执行结果
    bool setModuleResult(const string &moduleName, bool result);

    // 获取当前的模块数量
    int getCountOfAllModules(void);
    // 获取模块执行结果
    struct moduleResult * getModulesResults(void);
    // 针对数据口的有关接口
    /* 向模块管理器发送请求 */
    //  面向更灵活的请求接口
    struct moduleRespond *handleRequest(struct moduleRequest *request);
    //  直接解析 字符串命令
    struct moduleRespond *handleRequest(const string &requestStr);
    //  解析 命令行命令
    struct moduleRespond *handleRequest(int argc, char * argv[]);
    //  更加常规的请求
    struct moduleRespond *handleRequest(const string & run_mode, const string & cmd, const string & set_value);

private:
    /* data */
    // 测试模块映射，保存所有测试模块
    map<string, TestModule*> m_modulesMap;
    bool fullRunModule(class TestModule* module);
    //list<TestModule> modulesArray;
    // 线程池
    class threadPool *m_pool;
    // 存放测试结果的变量（每次获取时，都会进行动态拷贝）
    struct moduleResult *m_moduleResult;


    // 私有方法
    struct moduleRespond* handleRequestTypeGetStatusOfAllModulesWithCount(void);
    struct moduleRespond* makeSingleAck(struct moduleRequest *request,
                                        void *data, int size);
    struct moduleRespond* makeDataAck(const string &module);
    struct moduleRespond* handleRequestTypeGetPendingData(string & module);
    // 指定模块执行时可用参数
    void setModuleRuntimeArg(class TestModule* module, struct moduleRuntimeArg * runtimeArg);
};

#endif
